// TODO 装饰器目前基本都不支持直接使用，只能通过babel转换使用

import axios from 'axios'

// TODO 类装饰器
const Watcher: ClassDecorator = (target: Function) => {
	target.prototype.say = function () {
		console.log('say')
	}
}

@Watcher
class H {}

@Watcher
class G {}

const h = new H()
const g = new G()
;(<any>h).say()
;(<any>g).say()

// TODO 类装饰器-传递参数
const WatcherByParams = (data: string): ClassDecorator => {
	return (target: Function) => {
		target.prototype.show = function () {
			console.log(data)
		}
	}
}

@WatcherByParams('deng')
class K {}

const k = new K()
;(<any>k).show()

// TODO 多个装饰器
@WatcherByParams('deng')
@Watcher
class L {}

const l = new L()
;(l as any).show()

// TODO 属性装饰器
const WatcherProperty: PropertyDecorator = (...args) => {
	// console.log(args); // [ {}, '属性名', undefined ]
}
// TODO 方法装饰器
const WatcherMethod: MethodDecorator = (...args) => {
	// console.log(args); // [ {}, '方法名', 描述对象 ]
}
// TODO 方法装饰器-带参数
const Get = (url: string) => {
	return (target: any, key: any, descriptor: PropertyDescriptor) => {
		const func = descriptor.value
		axios
			.get(url)
			.then(res => {
				func(null, res.data)
			})
			.catch(err => {
				func(err, null)
			})
	}
}
// TODO 参数装饰器
const WatcherParameter: ParameterDecorator = (...args) => {
	// console.log(args); // [ [class U], undefined, 参数索引位置 ]
}

class U {
	age = 10
	@WatcherProperty
	name: string

	constructor(@WatcherParameter name: string) {
		this.name = name
	}

	@WatcherMethod
	@Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
	show(err: any, data: any) {
		console.log({ err, data })
	}
}
const u = new U('deng')
